package pe.com.bbva.targps.job;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import pe.com.bbva.carga.bo.ArchivoBO;
import pe.com.bbva.carga.bo.LoadClassTargpsBO;
import pe.com.bbva.carga.bo.ProcesoCargaBO;
import pe.com.bbva.carga.dao.LoadClassTargpsDAO;
import pe.com.bbva.carga.domain.Archivo;
import pe.com.bbva.carga.domain.ArchivoCarga;
import pe.com.bbva.carga.domain.ProcesoCarga;
import pe.com.bbva.configuracion.bo.ConfArchivoBO;
import pe.com.bbva.configuracion.bo.ConfiguracionBO;
import pe.com.bbva.configuracion.bo.TurnoBO;
import pe.com.bbva.configuracion.domain.ConfArchivo;
import pe.com.bbva.configuracion.domain.Configuracion;
import pe.com.bbva.configuracion.domain.Turno;
import pe.com.bbva.mantenimiento.bo.ParametroBO;
import pe.com.bbva.mantenimiento.bo.ProveedorBO;
import pe.com.bbva.mantenimiento.bo.TablaBO;
import pe.com.bbva.mantenimiento.domain.Parametro;
import pe.com.bbva.mantenimiento.domain.Proveedor;
import pe.com.bbva.mantenimiento.domain.Tabla;
import pe.com.bbva.util.Constantes;
import pe.com.bbva.util.Util;
import pe.com.stefanini.core.exceptions.BOException;
import pe.com.stefanini.core.exceptions.DAOException;
import pe.com.stefanini.core.util.FechaUtil;

@Service("loadTargpsJob")
public class LoadTargpsJob {

	Logger logger = Logger.getLogger(this.getClass());

	@Resource
	private LoadClassTargpsBO loadClassTargpsBO;
	
	@Resource
	private ConfiguracionBO configuracionBO;

	@Resource
	private TurnoBO turnoBO;

	@Resource
	private ConfArchivoBO confArchivoBO;

	@Resource
	private ParametroBO parametroBO;

	@Resource
	private TablaBO tablaBO;

	@Resource
	private ProveedorBO proveedorBO;

	@Resource
	private ProcesoCargaBO procesoCargaBO;
	
	@Resource
	private ArchivoBO archivoBO;
	
	@Resource
	private LoadClassTargpsDAO loadClassTargpsDAO;
		
	public void CargarAutomatico() throws BOException, DAOException {
		try {
			boolean detenerBusqueda = false;
			List<String> procesados = new ArrayList<String>();
			Parametro parametroFlg = parametroBO.findById(Constantes.FLAG_PROCESO);
			Long flagProceso = Long.valueOf(parametroFlg.getValor());
			if (flagProceso.equals(0L)) {
				desactivarProcesos();
				
				Turno turnoBuscar = turnoBO.findActive();
				Turno turno = null;
				if(turnoBuscar!=null){
					turno = turnoBuscar;
					Calendar cal = Calendar.getInstance();
					String horaInicioTmp = String.valueOf(cal.get(Calendar.HOUR_OF_DAY)) + String.valueOf(cal.get(Calendar.MINUTE));
					int inicio = Integer.parseInt(horaInicioTmp);
					String horaFinTmp = turno.getHoraFin().replaceAll(":", "");
					int fin = Integer.parseInt(horaFinTmp);
					if(inicio > fin){
	                	detenerBusqueda = true;
	                	turno.setEstadoEjecucion("0");
						turnoBO.save(turno, turno.getId());
	                }
				}else{
					Configuracion configuracion = configuracionBO.findById(Constantes.ID_CONFIG_CARGA);
					int intervalo = (int)(long) configuracion.getIntervalo();
					turnoBuscar = new Turno();
					Calendar hoy = Calendar.getInstance();
					String hora = hoy.get(Calendar.HOUR_OF_DAY)+":";
					int minuto = hoy.get(Calendar.MINUTE);
					int limiteInferior = minuto - intervalo;
					int limiteSuperior = minuto + intervalo;
					turnoBuscar.setHoraInicio(hora);
					turnoBuscar.setEstado("1");
					List<Turno> turnos = turnoBO.findTurnos(turnoBuscar);
					for(Turno turnoTmp: turnos){
						String []horaMinuto = turnoTmp.getHoraInicio().split(Pattern.quote(":"));
						int minutoTurno = Integer.parseInt(horaMinuto[1]);
						if(minutoTurno >= limiteInferior && minutoTurno <= limiteSuperior){
							turno = turnoTmp;
						}
					}
				}
				if(turno!=null){
					Parametro parametro = parametroBO.findById(Constantes.PARAMETRO_RUTA_CARGA);
					File directorio = new File(parametro.getValor());
					if(directorio.exists()){
						SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");
						Tabla incidenciaValor = null;
						String fechaArchivo = sdf.format(FechaUtil.getFechaActualDate());
						
						turno.setEstadoEjecucion("1");
						turnoBO.save(turno, turno.getId());
						
						// INICIO BUSCAR ARCHIVOS DE ESTAMPACION Y DE RETORNO
						ConfArchivo equipoBuscar = new ConfArchivo();
						equipoBuscar.setTurno(turno);
						List<ConfArchivo> equipos = confArchivoBO.findConfArchivo(equipoBuscar);
						for(ConfArchivo equipo: equipos){
							if(equipo.getEstado().equals(Constantes.ESTADO_ACTIVO)){
								int nroArchivo = 1;
								while(nroArchivo < 3){
									ArchivoCarga archivoCargar = new ArchivoCarga();
									archivoCargar.setIdTurno(turno.getId());
									archivoCargar.setIdEquipo(equipo.getEquipo().getId());
									archivoCargar.setFechaProceso(FechaUtil.getFechaActualDate());
									archivoCargar.setIdTipoCarga(Constantes.ID_TIPO_CARGA_AUTOMATICO);
									
									File file = null;
									String tipoArchivo = "";
									String nomArchivo = " ";
									
									ProcesoCarga proceso = new ProcesoCarga();
									Archivo archivo = new Archivo();
									ProcesoCarga procesoBuscar = new ProcesoCarga();
									procesoBuscar.setFechaProceso(FechaUtil.getFechaActualDate());
									procesoBuscar.setTurno(turno);
									procesoBuscar.setEquipo(equipo.getEquipo());
									List<ProcesoCarga> procesos = procesoCargaBO.findProcesosCarga(procesoBuscar);
									if (procesos == null || procesos.isEmpty()) {
										proceso.setFechaProceso(FechaUtil.getFechaActualDate());
										proceso.setTurno(turno);
										proceso.setEquipo(equipo.getEquipo());
										proceso.setEstadoFacturacion(String.valueOf(Constantes.ESTADO_PROCESO_NO_FACTURADO));
										proceso.setFormaFacturacion(String.valueOf(Constantes.TIPO_CARGA_AUTOMATICA));
										proceso.setCodUsuarioCreacion("ADMIN");
										proceso.setFechaCreacion(FechaUtil.getFechaActualDate());
										if(equipo.getObligatorio().equals(Constantes.ESTADO_ACTIVO)){
											procesoCargaBO.save(proceso);
										}
									} else {
										proceso = procesos.get(0);
										if(proceso.getEstado()!=null && proceso.getEstado().equals(String.valueOf(Constantes.ESTADO_PROCESO_COMPLETO))){
											nroArchivo = 4;
											continue;
										}
									}
									
									if(proceso.getEstadoAutomatico()!=null && proceso.getEstadoAutomatico().equals("1")){
										turno.setEstadoEjecucion("0");
										turnoBO.save(turno, turno.getId());
										break;
									}
									Archivo archivoBuscar = new Archivo();
									archivoBuscar.setIdProceso(proceso.getId());
									archivoCargar.setIdProceso(proceso.getId());
									Tabla tablaTipoCarga = getArchivoEquivalente((proceso.getEstado()==null?"":proceso.getEstado()));
									tipoArchivo = equipo.getEquipo().getDescripcion();
									archivoCargar.setIdTipoArchivo(tablaTipoCarga.getId());
									archivoCargar.setNombreArchivo("");
									
									List<Archivo> archivos = new ArrayList<Archivo>();
									int opc = (int)(long)tablaTipoCarga.getId();
									switch(opc){
									case 58:
										archivoBuscar.setTipo(String.valueOf(Constantes.ESTAMPACION));
										archivos = archivoBO.findArchivos(archivoBuscar);
										if(archivos!=null && !archivos.isEmpty()){
											archivo = archivos.get(0);
										}else{
											archivoCargar.setIdEquipo(equipo.getEquipo().getId());
											archivoCargar.setIdTipoArchivo(Constantes.ESTAMPACION);
											archivoCargar.setNombreArchivo(nomArchivo);
											archivo = loadClassTargpsBO.getCargaArchivo(archivoCargar);
											archivo.setFechaCargaFinal(FechaUtil.getFechaActualDate());
											if(equipo.getObligatorio().equals(Constantes.ESTADO_ACTIVO)){
												archivoBO.save(archivo);
											}
										}
										nomArchivo = Util.getFileFormat(String.valueOf(turno.getId()), equipo.getEquipo().getAbreviado(), "", fechaArchivo, Constantes.ARCHIVO_ESTAMPACION_DESC);
										file = new File(parametro.getValor() + "/" + nomArchivo);
										if(file.exists()){
											if(equipo.getObligatorio().equals(Constantes.ESTADO_INACTIVO)){
												procesoCargaBO.save(proceso);
											}
											if(equipo.getObligatorio().equals(Constantes.ESTADO_INACTIVO)){
												archivoBO.save(archivo);
											}
											archivoCargar.setNombreArchivo(nomArchivo);
											archivo.setNombreArchivo(nomArchivo);
											archivo.setEstadoCarga(String.valueOf(Constantes.ESTADO_CARGA_EXITO));
											archivo.setComentario("ARCHIVO DE ESTAMPACION DE " + equipo.getEquipo().getDescripcion() + ", CARGADO CON EXITO");
											archivoBO.save(archivo);
											String respuesta = loadClassTargpsDAO.cargarArchivo(archivoCargar);
											if(respuesta!=null && !respuesta.equals("")){
												archivo = archivoBO.findById(archivo.getId());
												archivo.setFechaCargaFinal(FechaUtil.getFechaActualDate());
												archivoBO.save(archivo);
												procesados.add(buildContent(nomArchivo, fechaArchivo, turno.getDescripcion(), equipo.getEquipo().getDescripcion(), tipoArchivo));
												nroArchivo++;
											}else{
												nroArchivo = 4;
												if(detenerBusqueda){
													incidenciaValor = tablaBO.findById(Constantes.I0003);
													configuracionBO.enviarEmailError(String.valueOf(incidenciaValor.getValor()), incidenciaValor.getDescripcion());
												}
											}
										}else{
											nroArchivo = 4;
											if(detenerBusqueda){
												incidenciaValor = tablaBO.findById(Constantes.I0003);
												Archivo buscar = new Archivo();
												buscar.setIdProceso(proceso.getId());
												buscar.setTipo(String.valueOf(Constantes.ESTAMPACION));
												List<Archivo> archivosTmp = archivoBO.findArchivos(buscar);
												if(archivosTmp!=null && !archivosTmp.isEmpty()){
													Archivo archivoActual = archivosTmp.get(0);
													archivoActual.setEstadoCarga(String.valueOf(Constantes.ESTADO_CARGA_FALLIDO));
													archivoActual.setComentario(equipo.getEquipo().getDescripcion().toUpperCase() + ": " + incidenciaValor.getDescripcion());
													archivoBO.save(archivoActual);
												}
												proceso.setEstado("");
												proceso.setEstadoAutomatico("1");
												procesoCargaBO.save(proceso);
												configuracionBO.enviarEmailError(String.valueOf(incidenciaValor.getValor()), incidenciaValor.getDescripcion());
											}
										}
										break;
								
									case 59:
										archivoBuscar.setTipo(String.valueOf(Constantes.RETORNO));
										archivos = archivoBO.findArchivos(archivoBuscar);
										if(archivos!=null && !archivos.isEmpty()){
											archivo = archivos.get(0);
										}else{
											archivoCargar.setIdEquipo(equipo.getEquipo().getId());
											archivoCargar.setIdTipoArchivo(Constantes.RETORNO);
											archivoCargar.setNombreArchivo(nomArchivo);
											archivo = loadClassTargpsBO.getCargaArchivo(archivoCargar);
											archivo.setFechaCargaFinal(FechaUtil.getFechaActualDate());
											archivoBO.save(archivo);
										}
										nomArchivo = Util.getFileFormat(String.valueOf(turno.getId()), equipo.getEquipo().getAbreviado(), "", fechaArchivo, Constantes.ARCHIVO_RETORNO_DESC);
										file = new File(parametro.getValor() + "/" + nomArchivo);
										if(file.exists()){
											archivoCargar.setNombreArchivo(nomArchivo);
											archivo.setNombreArchivo(nomArchivo);
											archivo.setEstadoCarga(String.valueOf(Constantes.ESTADO_CARGA_EXITO));
											archivo.setComentario("ARCHIVO DE RETORNO DE " + equipo.getEquipo().getDescripcion() + ", CARGADO CON EXITO");
											archivoBO.save(archivo);
											String respuesta = loadClassTargpsDAO.cargarArchivo(archivoCargar);
											if(respuesta!=null && !respuesta.equals("")){
												archivo = archivoBO.findById(archivo.getId());
												archivo.setFechaCargaFinal(FechaUtil.getFechaActualDate());
												archivoBO.save(archivo);
												procesados.add(buildContent(nomArchivo, fechaArchivo, turno.getDescripcion(), equipo.getEquipo().getDescripcion(), tipoArchivo));
												nroArchivo++;
											}else{
												nroArchivo = 4;
												if(detenerBusqueda){
													incidenciaValor = tablaBO.findById(Constantes.I0003);
													configuracionBO.enviarEmailError(String.valueOf(incidenciaValor.getValor()), incidenciaValor.getDescripcion());
												}
											}
										}else{
											nroArchivo = 4;
											if(detenerBusqueda){
												incidenciaValor = tablaBO.findById(Constantes.I0004);
												Archivo buscar = new Archivo();
												buscar.setIdProceso(proceso.getId());
												buscar.setTipo(String.valueOf(Constantes.RETORNO));
												List<Archivo> archivosTmp = archivoBO.findArchivos(buscar);
												if(archivosTmp!=null && !archivosTmp.isEmpty()){
													Archivo archivoActual = archivosTmp.get(0);
													archivoActual.setEstadoCarga(String.valueOf(Constantes.ESTADO_CARGA_FALLIDO));
													archivoActual.setComentario(equipo.getEquipo().getDescripcion().toUpperCase() + ": " + incidenciaValor.getDescripcion());
													archivoBO.save(archivoActual);
												}
												proceso.setEstado(String.valueOf(Constantes.ESTADO_PROCESO_SOLICITADO));
												proceso.setEstadoAutomatico("1");
												procesoCargaBO.save(proceso);
												configuracionBO.enviarEmailError(String.valueOf(incidenciaValor.getValor()), incidenciaValor.getDescripcion());
											}
										}
										break;
									
									case 60:
										nroArchivo++;
										break;
									}
								}
							}
						}
						// FIN BUSCAR ARCHIVOS DE ESTAMPACION Y DE RETORNO			
						
						//INICIO BUSCAR ARCHIVOS DE FALTANTES
						ProcesoCarga procesoBuscar = new ProcesoCarga();
						procesoBuscar.setFechaProceso(FechaUtil.getFechaActualDate());
						procesoBuscar.setTurno(turno);
						procesoBuscar.setEstado(String.valueOf(Constantes.ESTADO_PROCESO_ENTREGADO));
						List<ProcesoCarga> procesos = procesoCargaBO.findProcesosCarga(procesoBuscar);
						for(ProcesoCarga proceso: procesos){
							String nomArchivo = " ";
							
							Proveedor proveedorBusca = new Proveedor();
							proveedorBusca.setTipo(tablaBO.findById(Constantes.PROVEEDOR_TIPO_COURIER));
							List<Proveedor> proveedores = proveedorBO.findProveedores(proveedorBusca);
							for(Proveedor proveedor: proveedores){
								nomArchivo = Util.getFileFormat(String.valueOf(turno.getId()), proveedor.getNombreArchivo(), proveedor.getNombreArchivo(), sdf.format(FechaUtil.getFechaActualDate()), Constantes.ARCHIVO_FALTANTES_DESC);
								File file = new File(parametro.getValor() + "/" + nomArchivo);
								if(file.exists()){
									ArchivoCarga archivoCargar = new ArchivoCarga();
									archivoCargar.setIdEquipo(proceso.getEquipo().getId());
									archivoCargar.setIdTurno(proceso.getTurno().getId());
									archivoCargar.setFechaProceso(FechaUtil.getFechaActualDate());
									archivoCargar.setIdProceso(proceso.getId());
									archivoCargar.setIdTipoCarga(Constantes.ID_TIPO_CARGA_AUTOMATICO);
									
									Archivo archivo = null;
									Archivo archivoBuscar = new Archivo();
									archivoBuscar.setTipo(String.valueOf(Constantes.FALTANTES));
									List<Archivo> archivos = archivoBO.findArchivos(archivoBuscar);
									if(archivos!=null && !archivos.isEmpty()){
										archivo = archivos.get(0);
									}else{
										archivoCargar.setIdEquipo(proceso.getEquipo().getId());
										archivoCargar.setIdTipoArchivo(Constantes.ESTAMPACION);
										archivoCargar.setNombreArchivo(nomArchivo);
										archivo = loadClassTargpsBO.getCargaArchivo(archivoCargar);
										archivo.setFechaCargaFinal(FechaUtil.getFechaActualDate());
										archivoBO.save(archivo);
									}
									String respuesta = loadClassTargpsDAO.cargarArchivo(archivoCargar);
									if(respuesta!=null && !respuesta.equals("")){
										archivo = archivoBO.findById(archivo.getId());
										archivo.setFechaCargaFinal(FechaUtil.getFechaActualDate());
										archivoBO.save(archivo);
										procesados.add(buildContent(nomArchivo, fechaArchivo, turno.getDescripcion(), proceso.getEquipo().getDescripcion(), Constantes.ARCHIVO_FALTANTES_DESC));
									}else{
										if(detenerBusqueda){
											incidenciaValor = tablaBO.findById(Constantes.I0003);
											configuracionBO.enviarEmailError(String.valueOf(incidenciaValor.getValor()), incidenciaValor.getDescripcion());
										}
									}
								}else{
									if(detenerBusqueda){
										incidenciaValor = tablaBO.findById(Constantes.I0005);
										Archivo buscar = new Archivo();
										buscar.setIdProceso(proceso.getId());
										buscar.setTipo(String.valueOf(Constantes.FALTANTES));
										Archivo archivoActual = archivoBO.findArchivos(buscar).get(0);
										archivoActual.setEstadoCarga(String.valueOf(Constantes.ESTADO_CARGA_FALLIDO));
										archivoActual.setComentario(proceso.getEquipo().getDescripcion().toUpperCase() + ": " + incidenciaValor.getDescripcion());
										archivoBO.save(archivoActual);
										proceso.setEstado(String.valueOf(Constantes.ESTADO_PROCESO_ENTREGADO));
										proceso.setEstadoAutomatico("1");
										procesoCargaBO.save(proceso);
										configuracionBO.enviarEmailError(String.valueOf(incidenciaValor.getValor()), incidenciaValor.getDescripcion());
									}
								}
							}
						}
						//FIN BUSCAR ARCHIVOS DE FALTANTES
						if(!procesados.isEmpty()){
							configuracionBO.enviarEmailConsolidado(String.valueOf(turno.getId()), procesados);
						}
					}
					else{
						Tabla incidenciaValor = tablaBO.findById(Constantes.I0002);
						configuracionBO.enviarEmailError(String.valueOf(incidenciaValor.getValor()), "No existe la ruta consultada");
					}
				}
			}
			activarProcesos();
		} catch (Exception e) {
			activarProcesos();
			List<Turno> turnos = turnoBO.findTurnos(new Turno());
			for(Turno turno: turnos){
				turno.setEstadoEjecucion("0");
				turnoBO.save(turno, turno.getId());
			}
			logger.error(e.getMessage(), e);
		}
	}

	public void cargarArchivo(ArchivoCarga archivoCarga) {
		try {
			loadClassTargpsBO.cargarArchivo(archivoCarga);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	private void desactivarProcesos() {
		try {
			Parametro parametroMonitor = parametroBO.findById(Constantes.FLAG_PROCESO);
			parametroMonitor.setValor("1");
			parametroBO.update(parametroMonitor);
		} catch (Exception ex) {
			logger.error("Error al actualizar parametro monitor. " + ex.getMessage(), ex);
		}
	}
	
	private void activarProcesos() {
		try {
			Parametro parametroMonitor = parametroBO.findById(Constantes.FLAG_PROCESO);
			parametroMonitor.setValor("0");
			parametroBO.update(parametroMonitor);
		} catch (Exception ex) {
			logger.error("Error al actualizar parametro monitor. " + ex.getMessage(), ex);
		}
	}

	public Tabla getArchivoEquivalente(String estado) {
		Tabla tabla = null;
		try {
			if(estado.equals("")){
				tabla = tablaBO.findTablaById(Constantes.ESTAMPACION);
			}
			if(estado.equals(String.valueOf(Constantes.ESTADO_PROCESO_SOLICITADO))){
				tabla  = tablaBO.findTablaById(Constantes.RETORNO);
			}
			else if (estado.equals(String.valueOf(Constantes.ESTADO_PROCESO_ENTREGADO))) {
				tabla  = tablaBO.findTablaById(Constantes.FALTANTES);
			}
		} catch (BOException e) {
			e.printStackTrace();
		} catch (DAOException e) {
			e.printStackTrace();
		}
		return tabla;
	}
	
	public String buildContent(String nomArchivo, String fecha, String turno, String tipoArchivo, String tipoCarga){
		String contenido = "";
		contenido += "Nombre de Archivo: " + nomArchivo + ", ";
		contenido += "Fecha: " + fecha + ", Turno: " + turno;
		contenido += "Tipo de Archivo: " + tipoArchivo + ", ";
		contenido += "Tipo de Carga: " + tipoCarga;
		return contenido;
	}
}